package com.ks.winterwarmimage;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.ks.winterwarmimage.mqtt.MqttMag;
import com.ks.winterwarmimage.mqtt.MsgMqttService;
import com.ks.winterwarmimage.utils.BasicsUtil;
import com.ks.winterwarmimage.utils.CmdDataPacket;
import com.ks.winterwarmimage.utils.Constants;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;

public class OtaUpgradeActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG ="OtaUpgradeActivity" ;
    private static final String CMD_OTA="ota";
    private static final String base_topic="WinterWarmImage/dev/";
    /**升级开始*/
    private static final byte UPDATE_START= 0x01;
    /**升级完成*/
    private static final byte UPDATE_FINISH=0x02;
    /**正在更新（后面跟更新进度值和总大小,大端序）*/
    private static final byte UPDATE_PROGRESS=0x03;
    /**升级失败（后面紧跟失败原因代码，大端序）*/
    private static final byte UPDATE_FAILED=0x04;
    /**升级成功*/
    private static final byte UPDATE_SUCCESS=0x05;
    /**无更新*/
    private static final byte UPDATE_NO_UPDATES=0x06;
    /**升级结束*/
    private int update_state = 0;

    private TextView textDev,textState,textProgress;
    private EditText editFileUri;
    private ProgressBar progressOta;
    private TextView btnOta;
    private String deviceId=null;
    private String deviceName = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ota_upgrade);
        textDev = findViewById(R.id.text_dev);
        textState = findViewById(R.id.text_state);
        editFileUri = findViewById(R.id.edit_ota);
        textProgress= findViewById(R.id.text_progress);
        progressOta= findViewById(R.id.ota_progress);
        btnOta= findViewById(R.id.btn_ota);
        Bundle  bundle=this.getIntent().getExtras();
        if(bundle!=null) {
            if ( bundle.containsKey(Constants.KEY_MAC_ID)) {
                deviceId = bundle.getString(Constants.KEY_MAC_ID);
            }
            if(bundle.containsKey(Constants.KEY_DEV_NAME)){
                deviceName = bundle.getString(Constants.KEY_DEV_NAME);
            }
        }
        textDev.setText(deviceName);
        progressOta.setProgress(0);
        textProgress.setText(String.format(getString(R.string.title_ota_progress),0)+"%");

        bindMqttService();
        findViewById(R.id.img_return).setOnClickListener(this);
        btnOta.setOnClickListener(this);
    }
    @Override
    protected void onDestroy() {
        unMqttBroadcastReceiver();
        super.onDestroy();
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            Log.e(TAG,"按下Back或Home键退出");
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }
    @Override
    public void onClick(View view) {
        if(view.getId()==R.id.img_return){
            finish();
        }else  if(view.getId()==R.id.btn_ota){
            if(editFileUri.getText().toString().length()>0){
                String uri = editFileUri.getText().toString();
                byte[] uri_bytes=uri.getBytes(StandardCharsets.UTF_8);
                CmdDataPacket dataPacket=new CmdDataPacket(CmdDataPacket.COM_OTA_UPGRADE,uri_bytes);
                String id=BasicsUtil.removeMacColon(deviceId).toUpperCase();    //去除冒号
                String topic="WinterWarmImage/phone/"+id;//"/topic/mesh_cmd/"+group+"/"+childId;
                MsgMqttService.publish(topic,dataPacket.toBytes(),0,false);
                textState.setText(R.string.title_waiting_upgrade);
                progressOta.setProgress(0);
                textProgress.setText(String.format(getString(R.string.title_ota_progress),0)+"%");
                view.setEnabled(false);     //开始升级后禁用按钮
            }
        }
    }
    @Override
    protected void onMessageArrived(MqttMag message) {
        super.onMessageArrived(message);
        String topic = message.getTopic().replace(base_topic, "");  //去掉基主题部分
        String id= BasicsUtil.removeMacColon(deviceId);    //去除冒号
        if(id.equalsIgnoreCase(topic)){    //收到的消息和群组号一致
            receiveAnalysis(message.getMessage(),deviceId);
        }
    }
    /**
     * 接收解析处理
     * @param data
     * @param macId
     */
    private void receiveAnalysis(byte[] data,String macId) {
        if(macId!=null) {
            CmdDataPacket cmdDataPacket = CmdDataPacket.fromBytes(data);  //将消息转为标准命令结构
            if(cmdDataPacket!=null) {
                if (cmdDataPacket.command == CmdDataPacket.COM_OTA_UPGRADE_START) {
                    switch (cmdDataPacket.data[0]) {
                        case UPDATE_START: {
                            if (TextUtils.isEmpty(textState.getText())) {
                                textState.setText(R.string.title_start_ota);
                            } else {
                                textState.setText(textState.getText().toString() + "\n" + getString(R.string.title_start_ota));
                            }
                            update_state = UPDATE_START;
                            break;
                        }
                        case UPDATE_FINISH: {
                            if (TextUtils.isEmpty(textState.getText())) {
                                textState.setText(R.string.title_upgrade_finish);
                            } else {
                                textState.setText(textState.getText().toString() + "\n" + getString(R.string.title_upgrade_finish));
                            }
                            update_state = UPDATE_FINISH;
                            btnOta.postDelayed(otaFinishRunnable, 200);
                            break;
                        }
                        case UPDATE_PROGRESS: {
                            //升级进度
                            int cur = ByteBuffer.wrap(cmdDataPacket.data, 1, 4).order(ByteOrder.BIG_ENDIAN).getInt();
                            //总大小
                            int total = ByteBuffer.wrap(cmdDataPacket.data, 5, 4).order(ByteOrder.BIG_ENDIAN).getInt();
                            int progress = (int) (cur / (total / 100.0f));
                            progressOta.setProgress(progress);
                            String formatCurSize = formatFileSize(cur);
                            String formatTotalSize = formatFileSize(total);
                            String format = getString(R.string.title_upgrade_progress);
                            textProgress.setText(String.format(format, formatCurSize, formatTotalSize));
                            if (progressOta.getProgress() == 100) {
                                update_state = UPDATE_PROGRESS;
                                btnOta.postDelayed(otaFinishRunnable, 1000);
                            }
                            break;
                        }
                        case UPDATE_FAILED: {
                            if (TextUtils.isEmpty(textState.getText())) {
                                textState.setText(R.string.title_upgrade_fail);
                            } else {
                                textState.setText(textState.getText().toString() + "\n" + getString(R.string.title_upgrade_fail));
                            }
                            update_state = UPDATE_FAILED;
                            btnOta.postDelayed(otaFinishRunnable, 200);
                            break;
                        }
                        case UPDATE_SUCCESS: {
                            if (TextUtils.isEmpty(textState.getText())) {
                                textState.setText(R.string.title_upgrade_success);
                            } else {
                                textState.setText(textState.getText().toString() + "\n" + getString(R.string.title_upgrade_success));
                            }
                            update_state = UPDATE_SUCCESS;
                            btnOta.postDelayed(otaFinishRunnable, 200);
                            break;
                        }
                        case UPDATE_NO_UPDATES: {
                            if (TextUtils.isEmpty(textState.getText())) {
                                textState.setText(R.string.title_no_updates);
                            } else {
                                textState.setText(textState.getText().toString() + "\n" + getString(R.string.title_no_updates));
                            }
                            update_state = UPDATE_NO_UPDATES;
                            btnOta.postDelayed(otaFinishRunnable, 200);
                            break;
                        }
                    }
                } else if (cmdDataPacket.command == CmdDataPacket.COM_OTA_UPGRADE_ACK) {
                    textState.setText(R.string.title_ota_ack);
                }
            }
        }
    }
    /**
     * 转换文件大小
     *
     * @param fileSize 文件大小（以字节为单位）
     * @return 返回转换后的文件大小（包含单位）
     */
    private String formatFileSize(long fileSize) {
        DecimalFormat df=new DecimalFormat("#.00");
        String fileSizeString;
        String wrongSize="0B";
        if ( fileSize == 0 ) {
            return wrongSize;
        }
        if ( fileSize < 0x400 ) {
            fileSizeString=df.format((double) fileSize) + "B";
        } else if ( fileSize < 0x100000 ) {
            fileSizeString=df.format((double) fileSize / 0x400) + "KB";
        } else if ( fileSize < 0x40000000 ) {
            fileSizeString=df.format((double) fileSize / 0x100000) + "MB";
        } else {
            fileSizeString=df.format((double) fileSize / 0x40000000) + "GB";
        }
        return fileSizeString;
    }
    /**
     * 升级完成运行任务
     */
    final Runnable otaFinishRunnable = () -> {
        if(update_state==UPDATE_PROGRESS){
            if (TextUtils.isEmpty(textState.getText())) {
                textState.setText(R.string.title_upgrade_finish);
            } else {
                textState.setText(textState.getText().toString()+"\n"+getString(R.string.title_upgrade_finish));
            }
            update_state=UPDATE_FINISH;
            btnOta.postDelayed(OtaUpgradeActivity.this.otaFinishRunnable, 200);
        }else{
            progressOta.setProgress(0);
            textProgress.setText(String.format(getString(R.string.title_ota_progress), 0) + "%");
            btnOta.setEnabled(true);
        }
    };
}